package pattern.config.datasource;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import pattern.annontations.DataScope;
import pattern.constant.DefaultSystemConstant;
import pattern.currentsession.ContextLocalCache;
import pattern.model.AbstractBaseModel;
import pattern.utils.CollectionUtil;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 数据源处理
 * @author Simon
 * @date 2020-09-03 18:00
 **/
@Slf4j
@Order(-1)
@Aspect
@Component
public class DataSourceAop {

    @Autowired
    @Lazy
    private DataSourceRegister dataSourceRegister;

    @Around("execution(* pattern..*Service*.*(..)))")
    public Object source(ProceedingJoinPoint joinPoint) throws Throwable {
        try {
            var contextKey = DynamicDataSourceContextHolder.getContextKey();
            if(StringUtils.isBlank(contextKey)){
                //未设置数据源情况
                Object[] args = joinPoint.getArgs();
                for (Object arg : args) {
                    if (arg instanceof AbstractBaseModel) {
                        execParam((AbstractBaseModel) arg);
                    } else if (arg instanceof Object[]) {
                        for (Object o : (Object[]) arg) {
                            if (o instanceof AbstractBaseModel) {
                                execParam((AbstractBaseModel) o);
                            }
                        }
                    }
                }
                //没有指定数据源根据包名切换数据源
                if(StringUtils.isBlank(DynamicDataSourceContextHolder.getContextKey())) {
                    var defDatasourceKey = dataSourceRegister.getDefDatasourceKey();
                    if (CollectionUtil.isNotEmpty(defDatasourceKey)) {
                        Object target = joinPoint.getTarget();
                        String className = target.getClass().getName();
                        for (String key : defDatasourceKey) {
                            if (className.contains(key)) {
                                DynamicDataSourceContextHolder.setContextKey(key);
                                break;
                            }
                        }
                    }
                }
                if(StringUtils.isBlank(DynamicDataSourceContextHolder.getContextKey())){
                    DynamicDataSourceContextHolder.setContextKey(DefaultSystemConstant.PRIMARY_DATA_KEY);
                }
            }
            //设置DataScope
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            DataScope dataScope = method.getAnnotation(DataScope.class);
            if (Objects.nonNull(dataScope)) {
                if (Objects.nonNull(ContextLocalCache.get())) {
                    ContextLocalCache.get().setDataScope(dataScope);
                }
            }
            return joinPoint.proceed();
        } finally {
            if (Objects.nonNull(ContextLocalCache.get())) {
                ContextLocalCache.get().setDataScope(null);
            }
            DynamicDataSourceContextHolder.setContextKey(null);
        }
    }

    private void execParam(AbstractBaseModel o) {
        //处理传入的参数数据源key
        String dataSourcesKey = o.getDataSourcesKey();
        //切换数据源
        if (StringUtils.isNotBlank(dataSourcesKey)) {
            DynamicDataSourceContextHolder.setContextKey(dataSourcesKey);
        }
    }

}
